import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';

import 'FFTUtil.dart';
import 'listener/OnFftDataListener.dart';
import 'listener/OnMicCallback.dart';

class LibMic extends ChangeNotifier{
  //单例
  static LibMic? _instance;

  static LibMic get instance => _instance ??= LibMic._();
  final micMethodChannel = const MethodChannel("mic_method_channel");
  int lastTime = 0;
  //是否正在播放
  bool isPlaying = false;

  final List<OnMicCallback> _onMusicCallbackList = [];
  final List<OnFftDataListener> _onFftDataListenerList = [];

  void addOnMicCallback(OnMicCallback callback) {
    if (!_onMusicCallbackList.contains(callback)) {
      _onMusicCallbackList.add(callback);
    }
  }

  void removeOnMicCallback(OnMicCallback callback) {
    _onMusicCallbackList.remove(callback);
  }

  void addOnFftDataListener(OnFftDataListener listener) {
    if (!_onFftDataListenerList.contains(listener)) {
      _onFftDataListenerList.add(listener);
    }
  }

  void removeOnFftDataListener(OnFftDataListener listener) {
    _onFftDataListenerList.remove(listener);
  }

  LibMic._() {
    micMethodChannel.setMethodCallHandler((call) async {
      switch (call.method) {
        case "onMicData":
          if ((DateTime.now().millisecondsSinceEpoch - lastTime) > 100) {
            lastTime = DateTime.now().millisecondsSinceEpoch;
            List bytes = call.arguments["data"];
            //print("fft数据${bytes.length}");
            //print("麦克风数据:${bytes}");
            List<int> l = [];
            for (var b in bytes) {
              l.add(b);
            }
            while (l.length < 2048) {
              l.add(0);
            }

            for (var i = 0; i < l.length; i++) {
              l[i] = l[i].toSigned(8);
            }
            List<int> pcmShort = [];
            for (int i = 0; i < l.length / 2; i++) {
              pcmShort.add((l[2 * i] & 0xFF) | (l[2 * i + 1] << 8));
            }
            l = FFTUtil.fft(pcmShort);
            for (var listener in _onFftDataListenerList) {
              listener.onFftDataCapture(l);
            }
          }
          break;
      }
    });
  }

  void startRecord() {
    isPlaying = true;
    for (var listener in _onMusicCallbackList) {
      listener.onStartPlay();
    }
    micMethodChannel.invokeMethod("startRecord");
    notifyListeners();
  }

  void stopRecord() {
    isPlaying = false;
    micMethodChannel.invokeMethod("stopRecord");
    for (var listener in _onMusicCallbackList) {
      listener.onStopPlay();
    }
    notifyListeners();
  }
}
